home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’97 / Warrior’s Progress / source code / Source / Libraries / Lists / ListHead.cp < prev    next >
Encoding:
Text File  |  1997-06-28  |  4.2 KB  |  200 lines  |  [TEXT/CWIE]

  1. // ListHead.cp
  2.  
  3. #ifndef ListHead_h
  4. #include "ListHead.h"
  5. #endif
  6. #ifndef ListLink_h
  7. #include "ListLink.h"
  8. #endif
  9. #ifndef ListLoop_h
  10. #include "ListLoop.h"
  11. #endif
  12.  
  13. template < class Element >
  14. ListHead<Element>::ListHead()
  15.   : first( 0 ),
  16.      last( 0 ),
  17.      firstLoop( 0 )
  18.   {
  19.   }
  20.  
  21. template < class Element >
  22. ListHead<Element>::~ListHead()
  23.   {
  24.     Assert( IsEmpty() );
  25.     Assert( firstLoop == 0 );
  26.   }
  27.  
  28. template < class Element >
  29. void ListHead<Element>::Add( Link& link, BeforeStart )
  30.   {
  31.     Assert( !link.Listed() );
  32.     link.previous = 0;
  33.     link.next = first;
  34.     first = &link;
  35.     if ( link.next != 0 )
  36.         link.next->previous = &link;
  37.      else
  38.         last = &link;
  39.     link.head = this;
  40.  
  41.     for ( Loop *loop = firstLoop; loop != 0; loop = loop->nextLoop )
  42.         if ( loop->Unfinished() && loop->Null() && loop->previous == 0 )
  43.             loop->previous = &link;
  44.   }
  45.  
  46. template < class Element >
  47. void ListHead<Element>::Add( Link& link, AfterEnd )
  48.   {
  49.     Assert( !link.Listed() );
  50.     link.next = 0;
  51.     link.previous = last;
  52.     last = &link;
  53.     if ( link.previous != 0 )
  54.         link.previous->next = &link;
  55.      else
  56.         first = &link;
  57.     link.head = this;
  58.  
  59.     for ( Loop *loop = firstLoop; loop != 0; loop = loop->nextLoop )
  60.         if ( loop->Unfinished() && loop->Null() && loop->next == 0 )
  61.             loop->next = &link;
  62.   }
  63.  
  64. template < class Element >
  65. void ListHead<Element>::Add( Link& link, Before, const Link& position )
  66.   {
  67.     Assert( !link.Listed() );
  68.     Assert( position.head == this );
  69.     
  70.     link.next = const_cast< Link * >( &position );
  71.     link.previous = position.previous;
  72.     link.next->previous = &link;
  73.     if ( link.previous != 0 )
  74.         link.previous->next = &link;
  75.      else
  76.         first = &link;
  77.     link.head = this;
  78.  
  79.     for ( Loop *loop = firstLoop; loop != 0; loop = loop->nextLoop )
  80.         if ( loop->next == &position )
  81.             loop->next = &link;
  82.   }
  83.  
  84. template < class Element >
  85. void ListHead<Element>::Add( Link& link, After, const Link& position )
  86.   {
  87.     Assert( !link.Listed() );
  88.     Assert( position.head == this );
  89.     
  90.     link.next = position.next;
  91.     link.previous = const_cast< Link * >( &position );
  92.     link.previous->next = &link;
  93.     if ( link.next != 0 )
  94.         link.next->previous = &link;
  95.      else
  96.         last = &link;
  97.     link.head = this;
  98.  
  99.     for ( Loop *loop = firstLoop; loop != 0; loop = loop->nextLoop )
  100.         if ( loop->previous == &position )
  101.             loop->previous = &link;
  102.   }
  103.  
  104. template < class Element >
  105. void ListHead<Element>::Add( Link& link, Before, const Loop& position )
  106.   {
  107.     Assert( &position.head == this );
  108.     Assert( position.Unfinished() );
  109.     
  110.     if ( !position.Null() )
  111.         AddBefore( link, position.Link() );
  112.      else
  113.         if ( position.previous == 0 )
  114.             AddToHead( link );
  115.          else
  116.             AddAfter( *position.previous, link );
  117.   }
  118.  
  119. template < class Element >
  120. void ListHead<Element>::Add( Link& link, After, const Loop& position )
  121.   {
  122.     Assert( &position.head == this );
  123.     Assert( position.Unfinished() );
  124.     
  125.     if ( !position.Null() )
  126.         AddAfter( position.Link(), link );
  127.      else
  128.         if ( position.next == 0 )
  129.             AddToTail( link );
  130.          else
  131.             AddBefore( link, *position.next );
  132.   }
  133.  
  134. template < class Element >
  135. void ListHead<Element>::Remove( Link& link )
  136.   {
  137.     Assert( link.head == this );
  138.  
  139.     if ( link.next != 0 )
  140.         link.next->previous = link.previous;
  141.      else
  142.         last = link.previous;
  143.     
  144.     if ( link.previous != 0 )
  145.         link.previous->next = link.next;
  146.      else
  147.         first = link.next;
  148.     
  149.     for ( Loop *loop = firstLoop; loop != 0; loop = loop->nextLoop )
  150.       {
  151.         if ( loop->position == &link )
  152.           {
  153.             loop->position = 0;
  154.             loop->next = link.next;
  155.             loop->previous = link.previous;
  156.           }
  157.     
  158.         if ( loop->next == &link )
  159.             loop->next = link.next;
  160.         
  161.         if ( loop->previous == &link )
  162.             loop->previous = link.previous;
  163.       }
  164.     
  165.     link.previous = 0;
  166.     link.next = 0;
  167.     link.head = 0;
  168.   }
  169.  
  170. template < class Element >
  171. void ListHead<Element>::RemoveAll()
  172.   {
  173.     while( !IsEmpty() )
  174.         Remove( *first );
  175.   }
  176.  
  177. template < class Element >
  178. void ListHead<Element>::Register( Loop& loop ) const
  179.   {
  180.     Assert( &loop.head == this );
  181.     loop.nextLoop = firstLoop;
  182.     const_cast< Loop *& >( firstLoop ) = &loop;
  183.   }
  184.  
  185. template < class Element >
  186. void ListHead<Element>::Unregister( Loop& loop ) const
  187.   {
  188.     Assert( &loop.head == this );
  189.     
  190.     Loop** connection = const_cast< Loop ** >( &firstLoop );
  191.     while ( *connection != &loop )
  192.       {
  193.         Assert( *connection != 0 );
  194.         connection = &(*connection)->nextLoop;
  195.       }
  196.     
  197.     *connection = (*connection)->nextLoop;
  198.     loop.nextLoop = 0;
  199.   }
  200.